﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DataAccessLayer;
using GlobalObjects;
using System.Web;
using System.ServiceModel.Web;
using System.Net;
using System.Diagnostics;

namespace DataAccessLayerTests
{
    [TestClass]
    public class UserEntityTests
    {
        /// <summary>
        /// this is the first unit test for addUser(User newUser) method
        /// it uses a User object with a new username
        /// the expected result is a User object with an assigned id and also the username of the
        /// created record is as expected
        /// </summary>
        [TestMethod]
        public void addUser_DAL_validUser()
        {
            //arrange
            User newUser = new User();
            newUser.Username = "pejmanDeleteTesting";
            newUser.Password = "pejman";
            newUser.Title = "Mr";
            newUser.FirstName = "pejman";
            newUser.LastName = "aghili";
            newUser.Organisation = "MSR";
            newUser.Email = "pejman@gmail.com";
            newUser.Country = "U.K";
            newUser.Purpose = "Testing";
            UserEntity userEntity = new UserEntity();
            //act
            User createdUser = userEntity.addUser_DAL(newUser);
            //assert
            Assert.IsNotNull(createdUser.Id);
            Assert.AreEqual(newUser.Username, createdUser.Username);
            Assert.AreEqual(newUser.Title, createdUser.Title);
            Assert.AreEqual(newUser.FirstName, createdUser.FirstName);
            Assert.AreEqual(newUser.LastName, createdUser.LastName);
            Assert.AreEqual(newUser.Organisation, createdUser.Organisation);
            Assert.AreEqual(newUser.Email, createdUser.Email);
            Assert.AreEqual(newUser.Country, createdUser.Country);
            Assert.AreEqual(newUser.Purpose, createdUser.Purpose);
        }

        [TestMethod]
        public void addUser_DAL_isUserAdded()
        {
            //arrange
            User newUser = new User();
            newUser.Username = "unittest102";
            newUser.Password = "unittest102";
            newUser.Title = "Mr";
            newUser.FirstName = "unit";
            newUser.LastName = "test";
            newUser.Organisation = "msr";
            newUser.Email = "unit@gmail.com";
            newUser.Country = "U.K";
            newUser.Purpose = "Testing";
            UserEntity userEntity = new UserEntity();
            //act
            User createdUser = userEntity.addUser_DAL(newUser);
            //assert
            Assert.IsNotNull(createdUser.Id);
        }

        /// <summary>
        /// this is the second unit test for addUser(User newUser) method
        /// it uses a User object with a username that already exist in the DB
        /// assert is handled by ExpectedException
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(System.Data.Entity.Infrastructure.DbUpdateException))]
        public void addUser_DAL_existingUser()
        {
            //arrange
            User newUser = new User();
            newUser.Username = "peji";
            newUser.Password = "test";
            newUser.Title = "Mr";
            newUser.FirstName = "abc";
            newUser.LastName = "efg";
            newUser.Organisation = "fbi";
            newUser.Email = "123";
            newUser.Country = "US";
            newUser.Purpose = "Fun";
            UserEntity userEntity = new UserEntity();
            //act
            userEntity.addUser_DAL(newUser);
            // assert is handled by expected exception
        }

        /// <summary>
        /// unit test for encrypt(string password,string salt)
        /// </summary>
        [TestMethod]
        public void encrypt_sameresult()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            String password = "abc";
            String salt = "123";
            //act
            String hash1 = userEntity.encrypt(password, salt);
            String hash2 = userEntity.encrypt(password, salt);
            // assert
            Assert.AreEqual(hash1, hash2);
        }
        /// <summary>
        /// unit test 1 for checkUsername(String username)
        /// </summary>
        [TestMethod]
        public void checkUserName_exist()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            String username = "peji";
            //act
            Boolean exist = userEntity.checkUsernameDAL(username);
            // assert
            Assert.IsTrue(exist);
        }
        /// <summary>
        /// unit test 2 for checkUsername(String username)
        /// </summary>
        [TestMethod]
        public void checkUserName_notExist()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            String username = "random username";
            //act
            Boolean exist = userEntity.checkUsernameDAL(username);
            // assert
            Assert.IsFalse(exist);
        }

        /// <summary>
        /// unit test for  getUserById_DAL(int id)
        /// by passing a correct user id
        /// </summary>
        [TestMethod]
        public void getUserById_DAL_exist()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 16;
            //act
            UserDetails user = userEntity.getUserById_DAL(id);
            // assert
            Assert.AreEqual(user.FirstName, "Pejman");
            Assert.AreEqual(user.Username, "peji");
            Assert.AreEqual(user.EmailAddress, "pejiks@yahoo.com");
        }

        /// <summary>
        /// unit test for  getUserById_DAL(int id)
        /// by passing a incorrect user id
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void getUserById_DAL_notExist()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 122;
            //act
            UserDetails user = userEntity.getUserById_DAL(id);
            // assert handled by expected exception
        }

        /// <summary>
        /// unit test for updateUserById_DAL(int id, User userUpdated)
        /// valid id and valid details
        /// </summary>
        [TestMethod]
        public void updateUserById_DAL_valid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 19;
            User createduser = new User();
            createduser.Username = "peji3";
            createduser.Title = "Mr";
            createduser.FirstName = "unitUpdated";
            createduser.LastName = "testUpdated";
            createduser.Organisation = "msr";
            createduser.Email = "updated@gmail.com";
            createduser.Country = "U.KUpdated";
            createduser.Purpose = "TestingUpdated";
            //act
            UserDetails user = userEntity.updateUserById_DAL(id, createduser);
            // assert
            Assert.AreEqual(user.Id, 19);
            Assert.AreEqual(user.FirstName, "unitUpdated");
            Assert.AreEqual(user.LastName, "testUpdated");
            Assert.AreEqual(user.Organization, "msr");
            Assert.AreEqual(user.EmailAddress, "updated@gmail.com");
            Assert.AreEqual(user.Country, "U.KUpdated");
            Assert.AreEqual(user.Purpose, "TestingUpdated");
            Assert.AreEqual(user.Username, "peji3");

        }

        /// <summary>
        /// unit test for updateUserById_DAL(int id, User userUpdated)
        /// mismatch id
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void updateUserById_DAL_mismatchId()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 119;
            User createduser = new User();
            createduser.Username = "peji3";
            createduser.Title = "Mr";
            createduser.FirstName = "unitUpdated";
            createduser.LastName = "testUpdated";
            createduser.Organisation = "msr";
            createduser.Email = "updated@gmail.com";
            createduser.Country = "U.KUpdated";
            createduser.Purpose = "TestingUpdated";
            //act
            UserDetails user = userEntity.updateUserById_DAL(id, createduser);
            // assert handled by expected exception 
        }

        /// <summary>
        /// unit test for updateUserById_DAL(int id, User userUpdated)
        /// null values
        /// </summary>
        [TestMethod]
        public void updateUserById_DAL_nullValues()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 19;
            User createduser = new User();
            // createduser.Id = 19;
            createduser.Username = "peji3";
            createduser.Title = "Mr";
            createduser.FirstName = null;
            createduser.LastName = null;
            createduser.Organisation = "msr";
            createduser.Email = "updated@gmail.com";
            createduser.Country = "U.KUpdated";
            createduser.Purpose = "TestingUpdated";
            //act
            UserDetails user = userEntity.updateUserById_DAL(id, createduser);
            // assert
            Assert.AreEqual(user.Id, 19);
            Assert.AreEqual(user.FirstName, "unitUpdated");
            Assert.AreEqual(user.LastName, "testUpdated");
        }

        [TestMethod]
        public void deleteUser_DAL_validId()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 3202;
            string password = "pejman";
            //act
            Boolean result = userEntity.deleteUser_DAL(id, password);
            // assert
            Assert.AreEqual(result, true);
        }

        [TestMethod]
        public void deleteUser_DAL_invalidPassword()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 17;
            string password = "invalid";
            //act
            Boolean result = userEntity.deleteUser_DAL(id, password);
            // assert
            Assert.AreEqual(result, false);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void deleteUser_DAL_invalidId()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 10127;
            string password = "invalid";
            //act
            Boolean result = userEntity.deleteUser_DAL(id, password);
            // assert

        }

        [TestMethod]
        public void changePassword_valid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 1081;
            string password = "unittest101";
            string newPassword = "newString";
            //act
            Boolean result = userEntity.changePassword(id, password, newPassword);
            // assert
            Assert.IsTrue(result);
        }

        [TestMethod]
        public void changePassword_invalid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int id = 51;
            string password = "abc";
            string newPassword = "xvz";
            //act
            Boolean result = userEntity.changePassword(id, password, newPassword);
            // assert
            Assert.IsFalse(result);
        }

        /// <summary>
        /// unit test for checkLogin method. by checking a valid username and password
        /// </summary>
        [TestMethod]
        public void checkLogin_DAL_valid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            //act
            int result = userEntity.checkLogin_DAL("deletePassword", "xvz");
            // assert
            Assert.AreEqual(result, 51);
        }
        /// <summary>
        /// unit test for checkLogin method. by checking a invalid username and password
        /// </summary>
        [TestMethod]
        public void checkLogin_DAL_invalid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            //act
            int result = userEntity.checkLogin_DAL("incorrectPassword", "xvz");
            // assert
            Assert.AreEqual(result, 0);
        }

        [TestMethod]
        public void getUserIdByUsername_DAL_valid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            string username = "peji";
            //act
            int result = userEntity.getUserIdByUsername_DAL(username);
            // assert
            Assert.AreEqual(result, 16);
        }

        [TestMethod]
        [ExpectedException(typeof(System.Data.Entity.Infrastructure.DbUpdateException))]
        public void getUserIdByUsername_DAL_invalid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            string username = "abcxvz123";
            //act
            int result = userEntity.getUserIdByUsername_DAL(username);
            // assert

        }
        [TestMethod]
        public void getUserIdGivenSensorId_DAL_valid() {
            //arrange
            UserEntity userEntity = new UserEntity();
            int sensorId = 3372;
            //act
            int id =userEntity.getUserIdGivenSensorId_DAL(sensorId);
            //Assert
            Assert.AreEqual(id,1093);
        }
        [TestMethod]
        public void getUserIdGivenSensorId_DAL_invalid()
        {
            //arrange
            UserEntity userEntity = new UserEntity();
            int sensorId = 33722;
            //act
            int id = userEntity.getUserIdGivenSensorId_DAL(sensorId);
            //Assert
            Assert.AreEqual(id, 0);
        }
    }
}
